﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Shsc.Net.Common.Log;
using System.Reflection;
using System.IO;
using System.Xml.Serialization;
using Seasar.Framework.Aop;
using Seasar.Framework.Aop.Interceptors;

namespace Shsc.Net.Common.Seasar.Extension.Interceptor
{
    public class TraceInterceptor : AbstractInterceptor
    {
        /// <summary>
        /// Method執行前后的Log出力
        /// </summary>
        /// <param name="invocation"></param>
        /// <returns></returns>
        public override object Invoke(IMethodInvocation invocation)
        {
            object ret = null;
            Log4NetLogger logger = Log4NetLogger.CreateLogger(invocation.Target.GetType());
            StringBuilder buf = new StringBuilder();
            buf.Append(invocation.Target.GetType());
            buf.Append("#");
            buf.Append(invocation.Method.Name);

            string sMethod = buf.ToString();
            if (logger.IsDebugEnabled)
            {
                logBegin(logger, sMethod, invocation);
            }
            
            DateTime startTime = DateTime.Now;
            ret = invocation.Proceed();
            if (logger.IsDebugEnabled)
            {
                logEnd(logger, sMethod, invocation, ret, startTime);
            }
            return ret;

        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="sPrefix"></param>
        /// <param name="invocation"></param>
        private void logBegin(Log4NetLogger logger, string sPrefix, IMethodInvocation invocation)
        {
            logger.Debug("Class: [" + invocation.Target.GetType().Name + "]  "
                + "Method:[" + sPrefix + "]" + "Begin");
            object[] args = invocation.Arguments;
            ParameterInfo[] param = invocation.Method.GetParameters();
            if (param != null && param.Length > 0)
            {
                int index = 1;
                foreach (ParameterInfo obj in param)
                {
                    StringBuilder buf = new StringBuilder("Arg");
                    buf.Append(index);
                    buf.Append("[");
                    buf.Append(obj.Name);
                    buf.Append("]:");
                    buf.Append(toXml(args[index - 1]));
                    logger.Debug(buf.ToString());
                    index++;
                }
            }
        }



        private void logEnd(Log4NetLogger logger, string sPrefix, IMethodInvocation invocation,
            object ret, DateTime startTime)
        {
            logger.Debug("Class: [" + invocation.Target.GetType().Name + "]  "
                + "Method:[" + sPrefix + "]" + "End");
            if (ret != null)
            {
                logger.Debug("Result:" + toXml(ret));
            }
        }



        /// <summary>
        /// 參數序列化
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        private string toXml(object arg)
        {
            string strRet = string.Empty;
            if (arg != null)
            {
                using (StringWriter write = new StringWriter())
                {
                    new XmlSerializer(arg.GetType()).Serialize((TextWriter)write, arg);
                    StringBuilder buf = write.GetStringBuilder();
                    strRet = buf.ToString();
                    write.Close();
                }
            }
            return strRet;
        } 
    }
}
